﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

using VimApi;
using AppUtil;

using System.Web.Services.Protocols;


namespace VMware {

    /// <summary>
    /// Code from VMware samples directory...
    /// http://communities.vmware.com/community/developer/downloads
    /// </summary>
    public class VmPowerOps {
        private static AppUtil.AppUtil cb = null;
        static VimService _service;
        static ServiceContent _sic;

        private String _vmname = "";
        private String _powerOperation = "";
        
        //builtInOpts.Add("url", url);
        //    builtInOpts.Add("username", userName);
        //    builtInOpts.Add("password", password);
        //    builtInOpts.Add("config", config);
        //    builtInOpts.Add("protocol", protocol);
        //    builtInOpts.Add("server", server);
        //    builtInOpts.Add("portnumber", portNumber);
        //    builtInOpts.Add("servicepath", servicePath);
        //    builtInOpts.Add("sessionfile", sessionFile);
        //    builtInOpts.Add("help", help);
        //    builtInOpts.Add("ignorecert", ignorecert);


        public VmPowerOps(String vmname, String powerOperation) {

            String[] args = { "--url", "https://usppvmvc1.schcal.com/sdk", "--username", "vCenterSA", "--password", "FBC&len$458B" };

            cb = AppUtil.AppUtil.initialize("VmPowerOps", args);

            _vmname = vmname;
            _powerOperation = powerOperation;
            
            cb.connect();
            this.DoPowerOps();
            cb.disConnect();

        }


        private void DoPowerOps() {

            String vmName = _vmname;
            String powerOperation = _powerOperation;

            try {
                ManagedObjectReference vmmor = null;
                String errmsg = "";
                vmmor = cb.getServiceUtil().GetDecendentMoRef(null,
                                                              "VirtualMachine",
                                                              vmName);
                if (vmmor == null) {
                    errmsg = "Unable to find VirtualMachine named : "
                             + cb.get_option("vmname")
                             + " in Inventory";
                }
                Console.WriteLine(vmmor.type);
                

                ManagedObjectReference hostmor = cb.getServiceUtil().GetFirstDecendentMoRef(null, "HostSystem");
                bool nonTaskOp = false;
                ManagedObjectReference taskmor = null;
                if (powerOperation.Equals("on")) {
                    taskmor = cb.getConnection().Service.PowerOnVM_Task(vmmor, hostmor);
                }
                else if (powerOperation.Equals("off")) {
                    taskmor = cb.getConnection().Service.PowerOffVM_Task(vmmor);
                }
                else if (powerOperation.Equals("suspend")) {
                    taskmor = cb.getConnection().Service.SuspendVM_Task(vmmor);
                }
                else if (powerOperation.Equals("reset")) {
                    taskmor = cb.getConnection().Service.ResetVM_Task(vmmor);
                }
                else if (powerOperation.Equals("rebootGuest")) {
                    cb.getConnection().Service.RebootGuest(vmmor);
                    nonTaskOp = true;
                }
                else if (powerOperation.Equals("shutdownGuest")) {
                    cb.getConnection().Service.ShutdownGuest(vmmor);
                    nonTaskOp = true;
                }
                else if (powerOperation.Equals("standbyGuest")) {
                    cb.getConnection().Service.StandbyGuest(vmmor);
                    nonTaskOp = true;
                }
                else {
                    throw new Exception("Invaild power operation : " + powerOperation);

                }

                // If we get a valid task reference, monitor the task for success or failure
                // and report task completion or failure.
                if (taskmor != null) {
                    cb.log.LogLine("Got Valid Task Reference");

                    object[] result =
                       cb.getServiceUtil().WaitForValues(
                          taskmor, new string[] { "info.state", "info.error" },
                          new string[] { "state" }, // info has a property - state for state of the task
                          new object[][] { new object[] { TaskInfoState.success, TaskInfoState.error } }
                       );

                    // Wait till the task completes.
                    if (result[0].Equals(TaskInfoState.success)) {
                        cb.log.LogLine("VmPowerOps : : Successful " + powerOperation
                                       + " for VM : "
                                       + vmName);
                    }
                    else {
                        cb.log.LogLine("VmPowerOps : Failed " + powerOperation
                                       + " for VM : "
                                       + vmName);
                    }
                }
                else if (nonTaskOp) {
                    cb.log.LogLine("VmPowerOps : Successful " + powerOperation
                               + " for VM : "
                               + vmName);
                }
            }
            catch (Exception e) {
                cb.log.LogLine("VmPowerOps : Failed " + powerOperation + " for VM : " + vmName);
                throw e;
            }
        }

        public static OptionSpec[] constructOptions() {
            OptionSpec[] useroptions = new OptionSpec[3];
            useroptions[0] = new OptionSpec("vmname", "String", 1
                                            , "Name of Virtual Machine"
                                            , null);
            useroptions[1] = new OptionSpec("operation", "String", 1
                                            , "Operation [on|off|suspend|reset|rebootGuest]"
                                            , null);
            useroptions[2] = new OptionSpec("hostname", "String", 1
                                            , "Name of the host system"
                                            , null);
            return useroptions;
        }

    }

}

